#include "ringqueue.hpp"
#include "Task.hpp"
#include <ctime>
#include <sys/types.h>
#include <unistd.h>

pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER;

void *productor(void *rq_)
{
    // RingQueue<int> *rq = static_cast<RingQueue<int>*>(rq_);
    RingQueue<Task> *rq = static_cast<RingQueue<Task> *>(rq_);
    while (true)
    {
        // 生产任务
        // int t = rand() % 10;
        // rq->Push(t);
        // pthread_mutex_lock(&print_lock);
        // cout << "生产任务 : " << t << endl;
        // pthread_mutex_unlock(&print_lock);

        int x = rand() % 20;
        int y = rand() % 5;
        char op = oper[rand() % oper.size()];

        Task t(x, y, op, mymath);
        rq->Push(t);

        pthread_mutex_lock(&print_lock);
        cout << "生产者派发任务 : " << t.task_to_string() << endl;
        pthread_mutex_unlock(&print_lock);

        // sleep(1);
    }
    return nullptr;
}

void *consumer(void *rq_)
{
    // RingQueue<int> *rq = static_cast<RingQueue<int>*>(rq_);
    RingQueue<Task> *rq = static_cast<RingQueue<Task> *>(rq_);
    while (true)
    {
        // 消费任务
        // int t;
        // rq->Pop(&t);
        // pthread_mutex_lock(&print_lock);
        // cout << "消费任务 : " << t << endl;
        // pthread_mutex_unlock(&print_lock);

        Task t;
        rq->Pop(&t);
        string res = t();

        pthread_mutex_lock(&print_lock);
        cout << "消费者完成任务 : " << res << endl;
        pthread_mutex_unlock(&print_lock);

        sleep(1);
    }
    return nullptr;
}

int main()
{
    srand((unsigned int)time(nullptr) ^ getpid() ^ 0x20240319);

    // RingQueue<int> *rq = new RingQueue<int>();
    RingQueue<Task> *rq = new RingQueue<Task>();

    vector<pthread_t> p(4);
    vector<pthread_t> c(3);
    for(int i = 0; i < p.size(); i++) pthread_create(&p[i], nullptr, productor, rq);
    for(int i = 0; i < c.size(); i++) pthread_create(&c[i], nullptr, consumer, rq);

    for(int i = 0; i < p.size(); i++) pthread_join(p[i], nullptr);
    for(int i = 0; i < c.size(); i++) pthread_join(c[i], nullptr);


    // pthread_t p, c;
    // pthread_create(&p, nullptr, productor, rq);
    // pthread_create(&c, nullptr, consumer, rq);

    // pthread_join(p, nullptr);
    // pthread_join(c, nullptr);

    delete rq;
    return 0;
}